package com.example.demo.Interceptor;




import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.example.demo.common.R;
import com.example.demo.constans.CacheConstants;
import com.example.demo.excepiton.CustomException;
import com.example.demo.pojo.bo.LoginUserBo;
import com.example.demo.properties.IgnoreWhiteProperties;
import com.example.demo.service.IUserService;
import com.example.demo.utils.RedisService;
import com.example.demo.utils.SecurityUtils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.stream.Collectors;

/** 对需要带token访问的接口进行拦截
 * @Author mhx
 * @date 2022-06-30-2:10 下午
 */
@Component
@Slf4j
public class TokenInterceptor implements HandlerInterceptor {


    @Resource
    private IgnoreWhiteProperties ignoreWhiteProperties;

    @Resource
    private RedisService redisService;

    @Resource
    private IUserService iUserService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();
        if (com.example.demo.utils.StringUtils.matches(requestURI,ignoreWhiteProperties.getWhites())){
            return true;
        }
        String token = getToken(request);
        if (StringUtils.isEmpty(token)){
            throw new CustomException("令牌不能为空",401);
        }
        Long expireTimeByToken = SecurityUtils.getExpireTimeByToken(token);
        if (null ==expireTimeByToken ){
            throw new CustomException("令牌已过期",401);
        }

        Long userIdByToken = SecurityUtils.getUserIdByToken(token);
        String userStr = redisService.getValue(CacheConstants.LOGIN_TOKEN_KEY + userIdByToken);
        //---- 令牌
        if (StringUtils.isEmpty(userStr)){
            R<LoginUserBo> r = iUserService.saveUserInfoToRedis(token);
            LoginUserBo data = r.getData();
            List<LoginUserBo.permission> collect = data.getPermissions().stream().filter(e -> e.getPath().equals(requestURI)).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(collect)){
                throw new CustomException("你没有该权限",500);
            }

            if (r.getCode() == 500){
                throw new CustomException("非法用户",500);
            }
        }
        //查询用户登录次数跟黑名单，简单做一下基本逻辑
        String value1 = redisService.getValue("blackName:" + userIdByToken);
        if (!org.springframework.util.StringUtils.isEmpty(value1)){
            Long timeValue = redisService.getExpireTimeValue("blackName:" + userIdByToken);
            throw new CustomException("请在"+timeValue+"秒后登录",500);
        }
        String value = redisService.getValue("whiteNum:" + userIdByToken);
        if (org.springframework.util.StringUtils.isEmpty(value)){
            this.redisService.cacheValue("whiteNum:" + userIdByToken,"1",30);
        }else {
            this.redisService.cacheValue("whiteNum:" + userIdByToken,Integer.parseInt(value)+1+"",30);
        }

        return true;
    }
    private String getToken(HttpServletRequest request)
    {

        String token = request.getHeader(CacheConstants.HEADER);
        if (StringUtils.isNotEmpty(token) && token.startsWith(CacheConstants.TOKEN_PREFIX))
        {
            token = token.replace(CacheConstants.TOKEN_PREFIX, "");
        }
        log.info("==========Authorization:[{}]=========",token);
        return token;
    }
}
